home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The PC-SIG Library 10
/
The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso
/
PC_SIGCD
/
05
/
6
/
DISK0564.ZIP
/
SOURCE.ARC
/
ASM.ARC
/
FIXPATH.ASM
< prev
next >
Wrap
Assembly Source File
|
1989-01-19
|
8KB
|
225 lines
TITLE MSDOS2 PATHNAME PARSER
PATHSIZE EQU 65
.XLIST
INCLUDE MSDOS2.DEF
INCLUDE MACROS.DEF
.LIST
DOSSEG
.MODEL SMALL
.DATA
SSTARS DB '\'
STARS DB '*.*',0
DOTS DB '..',0
SLASHALONE DB '\',0
.DATA?
CURDIR DB PATHSIZE DUP (?)
DRIVE DB 1 DUP (?)
.CODE
EXTRN CPYCNT:NEAR
EXTRN SKIPSP:NEAR
EXTRN UC:NEAR
PUBLIC TYPE_UFN,TYPE_AFN,TYPE_DIR
PUBLIC TYPE_DSP,TYPE_DRV,TYPE_UNK
PUBLIC FIXPATH
; THIS PROCEDURE PARSES A (POSSIBLY AMBIGUOUS) DOS PATH NAME
; INTO A SEARCH PATH AND A LEAD-IN PATH. THE SEARCH PATH CAN
; BE USED AS AN ARGUMENT TO DOS FUNCTIONS 4E AND 4F. THE
; LEAD-IN PATH IS INTENDED TO BE PREFIXED TO THE SIMPLE FILENAME
; RETURNED BY THESE FUNCTIONS, IN ORDER TO PRODUCE A COMPLETE
; PATH NAME USABLE BY OPEN, RENAME, ETC.
;
; DS = ES IS ASSUMED.
;
; MODELLED AFTER THE C FUNCTION fixpath() IN DR. DOBB'S JOURNAL,
; OCT. 1985, PP. 16-18.
;
; ENTRY: BX - POINTS TO INPUT PATH
; CX - POINTS TO SEARCH PATH
; DX - POINTS TO LEAD-IN PATH
; EXIT:
; AX = 0 IF PATH IS AN UNAMBIGUOUS FILE NAME
; = 1 IF PATH IS AN AMBIGUOUS FILE NAME (E.G. "FOO?.*")
; = 2 IF PATH IS A DIRECTORY SPEC (E.G.: A:\FOO\BAR\")
; = 3 IF PATH IS A DRIVE SPEC (E.G. "A:") OR NULL STRING
; = 4 IF PATH IS A DIRECTORY
; = 5 IF PATH TYPE UNKNOWN OR DOES NOT EXIST
;
; USES: SI,DI,FLAGS
;
TYPE_UFN EQU 0
TYPE_AFN EQU 1
TYPE_DRV EQU 2
TYPE_DSP EQU 3
TYPE_DIR EQU 4
TYPE_UNK EQU 5
COPYPATH PROC NEAR
PUSH CX
MOV CX,PATHSIZE
CALL CPYCNT
POP CX
RET
COPYPATH ENDP
FIXPATH PROC NEAR
CALL SKIPSP
JB DRVSPEC ;IF NULL STRING
MOV BYTE PTR DRIVE, 0 ;SET DRIVE TO DEFAULT
CMP BYTE PTR [BX+1],':' ;CHECK FOR DRIVE SPEC
JNE NODSPEC ;IF NONE
MOV AL, BYTE PTR [BX] ;GET DRIVE LETTER
CALL UC ;MAKE UPPER-CASE
SUB AL, 'A'-1 ;MAKE BINARY
MOV BYTE PTR DRIVE, AL ;SAVE IT
CMP BYTE PTR [BX+2],0 ;CHECK FOR ONLY DRIVE SPEC
JE DRVSPEC ;IF THAT'S WHAT IT IS
NODSPEC:
MOV DI,BX
PUSH CX
MOV CX,PATHSIZE
XOR AX,AX
REPNE SCASB ;SEARCH FOR 0 BYTE
JCXZ TOOLONG ;IF PATH TOO LONG
GOTEND:
SUB DI,2 ;POINT TO LAST CHAR.
POP CX
MOV AL,[DI] ;GET LAST CHAR.
CMP AL,'\' ;IS IT BACKSLASH?
JNE FIXPATH2 ;NO.
MOV AX,TYPE_DSP
JMP SHORT DIRSPEC ;YES, IT IS, ASSUME (*.*)
TOOLONG:
POP CX
MOV AX,TYPE_UNK ;IF PATH TOO LONG
RET
DRVSPEC:
MOV AX,TYPE_DRV
DIRSPEC:
PUSH AX ;SAVE PATH TYPE
MOV SI,BX
MOV DI,DX
CALL COPYPATH ;COPY INPUT TO LEAD-IN PATH
MOV SI,BX
MOV DI,CX
CALL COPYPATH ;COPY INPUT TO SEARCH PATH
DEC DI ;BACK UP OVER NULL
MOV SI,OFFSET STARS
CALL COPYPATH ;NOW ADD "*.*" TO SEARCH PATH
POP AX ;RETURN PATH TYPE
RET
FIXPATH2:
MOV SI, OFFSET DOTS
MOV DI, BX
COMP_STRINGS ;SEE IF NAME = ".."
JNE NOTUPDIR
; .. is special case because CHMOD may not return its attribute
; correctly
PUSH DX
DOSCALL CURRENT_DISK ;GET CURRENT DISK
PUSH AX ;SAVE IT
MOV SI,OFFSET CURDIR
MOV BYTE PTR [SI],0 ;CLEAR DIRECTORY BUFFER
MOV DL, BYTE PTR DRIVE
DOSCALL CURRENT_DIR ;GET CURRENT DIRECTORY
POP DX
DOSCALL SELECT_DISK ;RESTORE CURRENT DISK
POP DX
CMP BYTE PTR CURDIR, 0 ;ROOT DIRECTORY?
JNE FIXPATH4 ;IF NOT ROOT DIRECTORY
MOV AX, TYPE_UNK ;.. AT ROOT, ERROR
JMP FIXPATH3
NOTUPDIR:
PUSH CX
PUSH DX
MOV DX,BX
MOV CX,0
MOV AL,0
DOSCALL CHMOD ;GET ATTRIBUTES FROM PATH
POP DX
JC BADNAME ;IF ERROR
TEST CX,0010H ;IS IT A DIRECTORY?
POP CX
MOV AX,TYPE_UFN ;SIGNAL UFN, JUST IN CASE
JZ FIXPATH3 ;IF NOT DIRECTORY, IS UFN
JMP SHORT FIXPATH4 ;IF DIRECTORY
BADNAME:
POP CX
CMP AX,3 ;IF ERROR CODE 3,
JZ TESTWILD ;MIGHT BE VALID (BUT AMBIGUOUS) PATH NAME
MOV AX,TYPE_UNK ;SET TYPE =UNKNOWN
JMP SHORT FIXPATH3 ;WEIRD ERROR CODE, TREAT PATH AS A UFN
TESTWILD: ;CAN'T GET ATTRIBUTES, SEE IF
PUSH BX ;PATH INCLUDES WILDCARDS
WLOOP: MOV AL,[BX]
CMP AL,0
JE NOTWILD
CMP AL,'*'
JE WILD
CMP AL,'?'
JE WILD
INC BX
JMP WLOOP
WILD: POP BX ;FOUND WILD CARD,
MOV AX,TYPE_AFN ;SET PATH TYPE = AFN
JMP SHORT FIXPATH3
NOTWILD:
POP BX ;NO WILD CARD FOUND,
MOV AX,TYPE_UNK ;SET PATH TYPE UNKNOWN
FIXPATH3: ;COME HERE IF PATH IS AFN, UFN OR UNKNOWN
PUSH AX
PUSH DX
PUSH BX
MOV SI,BX
MOV DI,CX
PUSH CX
CALL COPYPATH ;MAKE SEARCH PATH=INPUT PATH
POP DX ;DX = START OF PATH
MOV BX,DI ;BX = END OF PATH (1 PAST NULL)
DEC BX
SRCLUP:
CMP BX,DX ;BEFORE START OF PATH?
JL RETAIN ;YUP.
MOV AL,[BX] ;GET A CHAR. FROM PATH
CMP AL,'\' ;IS IT BACKSLASH OR COLON?
JE RETAIN
CMP AL,':'
JE RETAIN
DEC BX ;NO, BACK UP 1
JMP SRCLUP ;KEEP SEARCHING
RETAIN: INC BX
MOV [BX],BYTE PTR 0 ;ZAP WHATEVER IS AFTER ':' OR '\'
POP BX
POP DX
MOV SI,CX
MOV DI,DX
CALL COPYPATH ;COPY SEARCH PATH TO LEAD-IN PATH
MOV SI,BX
MOV DI,CX
CALL COPYPATH ;WHOLE INPUT FOR SEARCH
POP AX ;RESTORE TYPE
RET
FIXPATH4: ;COME HERE IF PATH IS A DIRECTORY
MOV SI,BX
MOV DI,CX
CALL COPYPATH ;COPY INPUT TO SEARCH PATH
DEC DI ;BACK UP OVER NULL
MOV SI,OFFSET SSTARS ;POINT TO "\*.*"
CALL COPYPATH ;ADD TO SEARCH PATH
MOV SI,BX
MOV DI,DX
CALL COPYPATH ;COPY INPUT TO LEAD-IN PATH
DEC DI ;BACK UP OVER NULL
MOV SI,OFFSET SLASHALONE ;POINT TO "\"
CALL COPYPATH ;ADD TO LEAD-IN PATH
MOV AX,TYPE_DIR ;SIGNAL DIRECTORY
RET
FIXPATH ENDP
END